#pragma once

#include "asocket.h"
#include <hash_map>
#include <queue>
#include "UDPPeer.h"
#include "NetMessageQueue.h"
#include "iNetMessageHandler.h"

namespace _FOGGE_
{
	namespace _NET_
	{
		class UDPSocket :
			public aSocket
		{
		public:
			enum __CONSTANT
			{
				eCONST_DefaultSendBufferSize=1024,
				eCONST_Ping_RecordLength=64,
				eCONST_Ping_DefaultValueLink=150,
				eCONST_Ping_DefaultValueTrans=200,
				eCONST_WaitTimeForResend=200,
			};

			UDPSocket(void);
			~UDPSocket(void);

			HRESULT SendMessage(NetMessage* ptrMsg);
			HRESULT Update(float ellpsedtime);
			void AddPeer(int peerid,char* peerip, BYTE peerport);
			void AddPeer(int peerid,unsigned peerip, BYTE peerport);
			void RemovePeer(int peerid);
			UDPPeer*	GetPeer(int peerID);
			void		SetLocalPeer(int peerID);
			int			GetLocalPeer();

			void Flush();
			
			void CheckPeerAlive();
			
			void ResetPings();

			HRESULT Bind(int port);


			void StartThread(LPTSTR ip,int port);
			void EndThread();

			void SetNetMessageHandler(iNetMessageHandler* _i_NetMessageHandler)
			{
				i_NetMessageHandler=_i_NetMessageHandler;
			}
			
		protected:

			void SetSocketOption();
			
			
			HRESULT FlushSendBuffer();
			int RecvData(LPWSABUF ptrBuffer);

			void OnRead(CommBuffer* ptrCommbuffer);


			void CreateSocket();


			std::queue<NetMessage*> m_SelfMessageQueue;
			int m_nLocalPeerID;

		private:
			bool SendToPeer(CommBuffer* ptrbuffer,UDPPeer* ptrPeer);


			std::map<int,UDPPeer*> m_PeerMap;
			iNetMessageHandler*	i_NetMessageHandler;	
		};


	}
}
